#include "..\\stdafx.h"
#include "wxWidgetsPaint.h"

MyColor::MyColor(){
    m_lastStyle = -1;
}
MyColor::~MyColor(){
    
}

static String m_systemFont;

void MyColor::setSystemFont(String value){
    m_systemFont = value;
}

String MyColor::getSystemFont(){
    if ((int)m_systemFont.length() == 0)
    {
        m_systemFont = L"SimSun";
    }
    return m_systemFont;
}

static int m_style = 0;

int MyColor::getStyle(){
    return m_style;
}
void MyColor::setStyle(int value){
    m_style = value;
}

void MyColor::createColors(){ 
	m_userColors.clear();
	if (m_style == 1)
    {
        m_userColors.put(FCColor_Back, FCColor::rgb(255, 255, 255)); //1
        m_userColors.put(FCColor_Border, FCColor::rgb(200, 200, 200)); //1
        m_userColors.put(FCColor_Text, FCColor::rgb(0, 0, 0)); //1
        m_userColors.put(FCColor_DisabledBack, FCColor::rgba(0, 0, 0, 25)); //1
        m_userColors.put(FCColor_DisabledText, 3289650);
        m_userColors.put(FCColor_Hovered, FCColor::rgba(43, 138, 195, 150));
        m_userColors.put(FCColor_Pushed, FCColor::rgba(43, 138, 195, 100));
    }else{
        m_userColors.put(FCColor_Back, FCColor::rgb(19, 21, 26));
        m_userColors.put(FCColor_Border, FCColor::rgb(50, 50, 50));
        m_userColors.put(FCColor_Text, FCColor::rgb(255, 255, 255));
        m_userColors.put(FCColor_DisabledBack, FCColor::rgba(255, 255, 255, 25));
        m_userColors.put(FCColor_DisabledText, 3289650);
        m_userColors.put(FCColor_Hovered, FCColor::rgba(43, 138, 195, 150));
        m_userColors.put(FCColor_Pushed, FCColor::rgba(43, 138, 195, 100));
    }
}

Long MyColor::getUserColor(Long color){
    if (m_lastStyle != m_style)
    {
        m_lastStyle = m_style;
       createColors();
    }
    if (m_userColors.containsKey(color))
    {
       color = m_userColors.get(color);
    }
    return color;
}

wxColour wxWidgetsPaint::getWxColor(Long dwPenColor) {
	Long c = dwPenColor;
	if (dwPenColor < FCColor_None)
	{
		dwPenColor = m_myColor->getUserColor(dwPenColor);
	}
	int a = 255;
	if (dwPenColor < 0)
	{
		dwPenColor = abs(dwPenColor);
		a = (int)(dwPenColor - dwPenColor / 1000 * 1000);
		dwPenColor /= 1000;
	}
	if (m_opacity < 1)
	{
		a = (int)(a * m_opacity);
	}
	int r = (int)(dwPenColor & 0xff);
	int g = (int)((dwPenColor >> 8) & 0xff);
	int b = (int)((dwPenColor >> 0x10) & 0xff);
	wxColour customColor(r, g, b);
	return customColor;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

wxWidgetsPaint::wxWidgetsPaint(){
	m_exportPath = L"";
	m_isClip = false;
	m_isPathStart = false;
	m_offsetX = 0;
	m_offsetY = 0;
	m_opacity = 1;
	m_pRect.left = 0;
	m_pRect.top = 0;
	m_pRect.right = 0;
	m_pRect.bottom = 0;
	m_resourcePath = L"";
	m_rotateAngle = 0;
	m_scaleFactorX = 0;
	m_scaleFactorY = 0;
	m_wRect.left = 0;
	m_wRect.top = 0;
	m_wRect.right = 0;
	m_wRect.bottom = 0;
	m_myColor = new MyColor;
	m_dc = 0;
}

wxWidgetsPaint::~wxWidgetsPaint(){
	clearCaches();
	if(m_myColor){
		delete m_myColor;
		m_myColor = 0;
	}
	m_dc = 0;
}

void wxWidgetsPaint::addArc(const FCRect& rect, float startAngle, float sweepAngle){

}

void wxWidgetsPaint::addBezier(FCPoint *apt, int cpt){
}

void wxWidgetsPaint::addCurve(FCPoint *apt, int cpt){
}

void wxWidgetsPaint::addEllipse(const FCRect& rect){

}

void wxWidgetsPaint::addLine(int x1, int y1, int x2, int y2){
	int lx1 = x1 + m_offsetX;
	int ly1 = y1 + m_offsetY;
	int lx2 = x2 + m_offsetX;
	int ly2 = y2 + m_offsetY;
	if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
	{
		lx1 = (int)(m_scaleFactorX * lx1);
		ly1 = (int)(m_scaleFactorY * ly1);
		lx2 = (int)(m_scaleFactorX * lx2);
		ly2 = (int)(m_scaleFactorY * ly2);
	}
	if (m_isPathStart)
	{
		m_isPathStart = false;
	}
}

void wxWidgetsPaint::addRect(const FCRect& rect){
}

void wxWidgetsPaint::addPie(const FCRect& rect, float startAngle, float sweepAngle){

}

void wxWidgetsPaint::addText(String strText, FCFont *font, const FCRect& rect, int width){
	
}

void wxWidgetsPaint::beginExport(const String& exportPath, const FCRect& rect){
	m_exportPath = exportPath;
    m_opacity = 1;
    m_resourcePath = L"";
}

void wxWidgetsPaint::beginPaint(HDC hDC, const FCRect& wRect, const FCRect& pRect){	
	m_pRect = pRect;
	m_wRect = wRect;
	m_opacity = 1;
	m_resourcePath = L"";
	m_isClip = false;
	m_isPathStart = false;
}

void wxWidgetsPaint::beginPath(){
}

void wxWidgetsPaint::clearCaches(){

}

void wxWidgetsPaint::clipPath(){
}

void wxWidgetsPaint::closeFigure(){

}

void wxWidgetsPaint::closePath(){
	m_isPathStart = false;
}

void wxWidgetsPaint::drawArc(Long dwPenColor, float width, int style, const FCRect& rect, float startAngle, float sweepAngle){
	if (dwPenColor == FCColor_None) return;
}

void wxWidgetsPaint::drawBezier(Long dwPenColor, float width, int style, FCPoint *apt, int cpt){

}

void wxWidgetsPaint::drawCurve(Long dwPenColor, float width, int style, FCPoint *apt, int cpt){
	
}

void wxWidgetsPaint::drawEllipse(Long dwPenColor, float width, int style, const FCRect& rect){
	if (dwPenColor == FCColor_None) return;
	FCRect drawRect = { (rect.left + m_offsetX) * m_scaleFactorX, (rect.top + m_offsetY) * m_scaleFactorY, (rect.right + m_offsetX) * m_scaleFactorX, (rect.bottom + m_offsetY) * m_scaleFactorY };
	wxPen pen(getWxColor(dwPenColor));
	m_dc->SetPen(pen);
	m_dc->SetBrush(*wxTRANSPARENT_BRUSH);
	m_dc->DrawEllipse(drawRect.left, drawRect.top, drawRect.right - drawRect.left, drawRect.bottom - drawRect.top);
}

void wxWidgetsPaint::drawEllipse(Long dwPenColor, float width, int style, int left, int top, int right, int bottom){
	FCRect rect = {left, top, right, bottom};
    drawEllipse(dwPenColor, width, style, rect);
}

void wxWidgetsPaint::drawImage(String imagePath, const FCRect& rect){
}

void wxWidgetsPaint::drawLine(Long dwPenColor, float width, int style, const FCPoint& x, const FCPoint& y){
	drawLine(dwPenColor, width, style, x.x, x.y, y.x, y.y);
}

void wxWidgetsPaint::drawLine(Long dwPenColor, float width, int style, int x1, int y1, int x2, int y2){
	if (dwPenColor == FCColor_None) return;
	float lineWidth = (float)(width * min(m_scaleFactorX, m_scaleFactorY));
	wxPen pen(getWxColor(dwPenColor));
	m_dc->SetPen(pen);
	int lx1 = x1 + m_offsetX;
	int ly1 = y1 + m_offsetY;
	int lx2 = x2 + m_offsetX;
	int ly2 = y2 + m_offsetY;
	if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
	{
		lx1 = (int)(m_scaleFactorX * lx1);
		ly1 = (int)(m_scaleFactorY * ly1);
		lx2 = (int)(m_scaleFactorX * lx2);
		ly2 = (int)(m_scaleFactorY * ly2);
	}
	m_dc->DrawLine(lx1, ly1, lx2, ly2);
}

void wxWidgetsPaint::drawPath(Long dwPenColor, float width, int style){
	if (dwPenColor == FCColor_None) return;
}

void wxWidgetsPaint::drawPie(Long dwPenColor, float width, int style, const FCRect& rect, float startAngle, float sweepAngle){

}

void wxWidgetsPaint::drawPolygon(Long dwPenColor, float width, int style, FCPoint *apt, int cpt){
	if (dwPenColor == FCColor_None) return;
	wxPen pen(getWxColor(dwPenColor));
	m_dc->SetPen(pen);
	float lineWidth = (float)(width * min(m_scaleFactorX, m_scaleFactorY));
	int lx = 0, ly = 0;
	int fx = 0, fy = 0;
	for (int i = 0; i < cpt; i++)
	{
		int x = apt[i].x + m_offsetX;
		int y = apt[i].y + m_offsetY;
		if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
		{
			x = (int)(m_scaleFactorX * x);
			y = (int)(m_scaleFactorY * y);
		}
		if (i > 0) {
			m_dc->DrawLine(lx, ly, x, y);
			if (i == cpt - 1) {
				m_dc->DrawLine(x, y, fx, fy);
			}
		}
		else {
			fx = x;
			fy = y;
		}
		lx = x;
		ly = y;
	}
}

void wxWidgetsPaint::drawPolyline(Long dwPenColor, float width, int style, FCPoint *apt, int cpt){
	if (dwPenColor == FCColor_None) return;
	wxPen pen(getWxColor(dwPenColor));
	m_dc->SetPen(pen);
	float lineWidth = (float)(width * min(m_scaleFactorX, m_scaleFactorY));
	int lx = 0, ly = 0;
	for (int i = 0; i < cpt; i++)
	{
		int x = apt[i].x + m_offsetX;
		int y = apt[i].y + m_offsetY;
		if (m_scaleFactorX != 1 || m_scaleFactorY != 1)
		{
			x = (int)(m_scaleFactorX * x);
			y = (int)(m_scaleFactorY * y);
		}
		if (i > 0) {
			m_dc->DrawLine(lx, ly, x, y);
		}
		lx = x;
		ly = y;
	}
}

void wxWidgetsPaint::drawRect(Long dwPenColor, float width, int style, int left, int top, int right, int bottom){
	FCRect rect = {left, top, right, bottom};
    drawRect(dwPenColor, width, style, rect);
}

void wxWidgetsPaint::drawRect(Long dwPenColor, float width, int style, const FCRect& rect) {
	if (dwPenColor == FCColor_None) return;
	wxPen pen(getWxColor(dwPenColor));
	m_dc->SetPen(pen);
	m_dc->SetBrush(*wxTRANSPARENT_BRUSH);
	FCRect drawRect = { (rect.left + m_offsetX) * m_scaleFactorX, (rect.top + m_offsetY) * m_scaleFactorY, (rect.right + m_offsetX) * m_scaleFactorX, (rect.bottom + m_offsetY) * m_scaleFactorY };
	m_dc->DrawRectangle(drawRect.left, drawRect.top, drawRect.right - drawRect.left, drawRect.bottom - drawRect.top);
}

void wxWidgetsPaint::drawRoundRect(Long dwPenColor, float width, int style, const FCRect& rect, int cornerRadius){
	drawRect(dwPenColor, width, style, rect);
}

void wxWidgetsPaint::drawText(String strText, Long dwPenColor, FCFont *font, const FCRect& rect, int width){
	if (dwPenColor == FCColor_None) return;
	String fontFamily = font->m_fontFamily;
	String newFont = L"";
	if (fontFamily == L"Default")
	{
		String sysFont = MyColor::getSystemFont();
		newFont = sysFont;
	}
	else
	{
		newFont = font->m_fontFamily;
	}
	int strX = (int)(m_scaleFactorX * (rect.left + m_offsetX));
	int strY = (int)(m_scaleFactorY * (rect.top + m_offsetY));
	float fontSize = (float)(font->m_fontSize * (m_scaleFactorX + m_scaleFactorY) / 2);
	FCFont scaleFont(font->m_fontFamily, fontSize, font->m_bold, font->m_underline, font->m_italic);
	wxString wxStr = FCTran::StringTostring(strText).c_str();
	wxFont wFont((int)fontSize - 2, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
	m_dc->SetFont(wFont);
	m_dc->SetTextForeground(getWxColor(dwPenColor));
	m_dc->DrawText(wxStr, strX, strY);
}

void wxWidgetsPaint::drawText(String strText, Long dwPenColor, FCFont *font, const FCRectF& rect, int width){
	FCRect lRect = { rect.left, rect.top, rect.right, rect.bottom };
	drawText(strText, dwPenColor, font, lRect, -1);
}

void wxWidgetsPaint::drawTextAutoEllipsis(String strText, Long dwPenColor, FCFont *font, const FCRect& rect){
	drawText(strText, dwPenColor, font, rect, -1);
}

void wxWidgetsPaint::endExport(){
    m_offsetX = 0;
    m_offsetY = 0;
    m_opacity = 1;
    m_resourcePath = L"";
}

void wxWidgetsPaint::endPaint(){
	m_offsetX = 0;
	m_offsetY = 0;
	m_opacity = 1;
	m_resourcePath = L"";
	FCRect rect = { 0, 0, 300, 300 };
}

void wxWidgetsPaint::excludeClipPath(){
}

void wxWidgetsPaint::fillEllipse(Long dwPenColor, const FCRect& rect){
	if (dwPenColor == FCColor_None) return;
	m_dc->SetPen(*wxTRANSPARENT_PEN);
	wxBrush brush(getWxColor(dwPenColor));
	m_dc->SetBrush(brush);
	FCRect drawRect = { (rect.left + m_offsetX) * m_scaleFactorX, (rect.top + m_offsetY) * m_scaleFactorY, (rect.right + m_offsetX) * m_scaleFactorX, (rect.bottom + m_offsetY) * m_scaleFactorY };
	m_dc->DrawEllipse(drawRect.left, drawRect.top, drawRect.right - drawRect.left, drawRect.bottom - drawRect.top);
}

void wxWidgetsPaint::fillGradientEllipse(Long dwFirst, Long dwSecond, const FCRect& rect, int angle){
	fillEllipse(dwFirst, rect);
}

void wxWidgetsPaint::fillGradientPath(Long dwFirst, Long dwSecond, const FCRect& rect, int angle){
	fillPath(dwFirst);
}

void wxWidgetsPaint::fillGradientPolygon(Long dwFirst, Long dwSecond, FCPoint *apt, int cpt, int angle){
	fillPolygon(dwFirst, apt, cpt);
}

void wxWidgetsPaint::fillGradientRect(Long dwFirst, Long dwSecond, const FCRect& rect, int cornerRadius, int angle){
	fillRect(dwFirst, rect);
}

void wxWidgetsPaint::fillPath(Long dwPenColor){
	if (dwPenColor == FCColor_None) return;
}

void wxWidgetsPaint::fillPie(Long dwPenColor, const FCRect& rect, float startAngle, float sweepAngle){

}

void wxWidgetsPaint::fillPolygon(Long dwPenColor, FCPoint *apt, int cpt){
}

void wxWidgetsPaint::fillRect(Long dwPenColor, const FCRect& rect){
	fillRect(dwPenColor, rect.left, rect.top, rect.right, rect.bottom);
}

void wxWidgetsPaint::fillRect(Long dwPenColor, int left, int top, int right, int bottom){
	if (dwPenColor == FCColor_None) return;
	m_dc->SetPen(*wxTRANSPARENT_PEN);
	wxBrush brush(getWxColor(dwPenColor));
	m_dc->SetBrush(brush);
	FCRect drawRect = { (left + m_offsetX) * m_scaleFactorX, (top + m_offsetY) * m_scaleFactorY, (right + m_offsetX) * m_scaleFactorX, (bottom + m_offsetY) * m_scaleFactorY };
	m_dc->DrawRectangle(drawRect.left, drawRect.top, drawRect.right - drawRect.left, drawRect.bottom - drawRect.top);
}

void wxWidgetsPaint::fillRoundRect(Long dwPenColor, const FCRect& rect, int cornerRadius){
	fillRect(dwPenColor, rect);
}

Long wxWidgetsPaint::getColor(Long dwPenColor){
	return m_myColor->getUserColor(dwPenColor);
}

Long wxWidgetsPaint::getPaintColor(Long dwPenColor){
	return getColor(dwPenColor);
}

FCPoint wxWidgetsPaint::getOffset(){
	FCPoint offset = {m_offsetX, m_offsetY};
	return offset;
}

void wxWidgetsPaint::getScaleFactor(double *scaleFactorX, double *scaleFactorY){
	*scaleFactorX = m_scaleFactorX;
	*scaleFactorY = m_scaleFactorY;
}

FCPoint wxWidgetsPaint::rotate(const FCPoint& op, const FCPoint& mp, int angle){
    float PI = 3.14159265f;
	FCPoint pt = {0};
    pt.x = (int)((mp.x - op.x) * cos(angle * PI / 180) - (mp.y - op.y) * sin(angle * PI / 180) + op.x);
    pt.y = (int)((mp.x - op.x) * sin(angle * PI / 180) + (mp.y - op.y) * cos(angle * PI / 180) + op.y);
    return pt;
}

void wxWidgetsPaint::setClip(const FCRect& rect){
	if (m_isClip) {
		m_dc->DestroyClippingRegion();
	}
	m_isClip = true;
	FCRect drawRect = { (rect.left + m_offsetX) * m_scaleFactorX, (rect.top + m_offsetY) * m_scaleFactorY, (rect.right + m_offsetX) * m_scaleFactorX, (rect.bottom + m_offsetY) * m_scaleFactorY };
	m_dc->SetClippingRegion(drawRect.left, drawRect.top, drawRect.right - drawRect.left, drawRect.bottom - drawRect.top);
}

void wxWidgetsPaint::setLineCap(int startLineCap, int endLineCap){
    
}

void wxWidgetsPaint::setOffset(const FCPoint& offset){
	m_offsetX = offset.x;
	m_offsetY = offset.y;
}

void wxWidgetsPaint::setOpacity(float opacity){
	if(m_opacity != opacity){
		m_opacity = opacity;
	}
}

void wxWidgetsPaint::setResourcePath(const String& resourcePath){
	m_resourcePath = resourcePath;
}

void wxWidgetsPaint::setRotateAngle(int rotateAngle){
	m_rotateAngle = rotateAngle;
}

void wxWidgetsPaint::setScaleFactor(double scaleFactorX, double scaleFactorY){
	m_scaleFactorX = scaleFactorX;
	m_scaleFactorY = scaleFactorY;
}

bool wxWidgetsPaint::supportTransparent(){
	return true;
}

FCSize wxWidgetsPaint::textSize(String strText, FCFont *font, int width){
	FCSizeF fSize = textSizeF(strText, font, width);
	FCSize size = { fSize.cx, fSize.cy };
	return size;
}

FCSizeF wxWidgetsPaint::textSizeF(String strText, FCFont *font, int width){
	String fontFamily = font->m_fontFamily;
	String newFont = L"";
	if (fontFamily == L"Default")
	{
		newFont = MyColor::getSystemFont();
	}
	else
	{
		newFont = font->m_fontFamily;
	}
	float rate = (float)((m_scaleFactorX + m_scaleFactorY) / 2);
	wxString wxStr = FCTran::StringTostring(strText).c_str();
	int cx = 0, cy = 0;
	float fontSize = (float)(font->m_fontSize * rate);
	wxFont wFont((int)fontSize - 2, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
	m_dc->SetFont(wFont);
	m_dc->GetTextExtent(wxStr, &cx, &cy);
	FCSizeF tSize = { cx / rate, cy / rate };
	return tSize;
}
